<template>
  <div class="form-modal-container">
    <a-modal :mask-closable="false" :ok-loading="okLoading" :width="width" v-model:visible="showDialog" :title="title"
      :ok-text="submitButtonName" @cancel="handleClose" @before-ok="submitBranchForm">
      <a-spin :loading="loading" tip="数据加载中">
        <a-form ref="ruleFormRef" :model="localForm" :rules="formRules ?? undefined">
          <a-row class="row-container">
            <a-col v-for="(item, index) in formInfo" :key="item.field" :span="item.span ? item.span : 24">
              <a-form-item :field="item.field" :label="item.label" :help="item.help ?? undefined"
                :validate-trigger="item.validateTrigger ?? 'change'" :validate-status="item.validateStatus ?? undefined"
                :feedback="item.feedback ?? false">
                <!-- input输入框 -->
                <a-input v-if="item.type == 'input'" class="edit-form-input" v-model="localForm[item.field]"
                  :placeholder="item.placeholder" :readonly="item.readonly" :disabled="item.disabled" allow-clear />

                <!-- 选择框 -->
                <a-select v-else-if="item.type == 'select'" :readonly="item.readonly" :disabled="item.disabled"
                  v-model="localForm[item.field]" :placeholder="item.placeholder" :multiple="item.multiple"
                  :max-tag-count="3" allow-clear>
                  <a-option v-for="dictItem in item.options!.value" :value="dictItem[item.optionProps!.value]">{{
                    dictItem[item.optionProps!.label] }}</a-option>
                </a-select>

                <!-- 级联选择器 -->
                <a-cascader v-else-if="item.type == 'cascader'" :readonly="item.readonly" :disabled="item.disabled"
                  :options="item.options!.value" v-model="localForm[item.field]" :placeholder="item.placeholder"
                  :check-strictly="item.checkStrictly" :max-tag-count="3" :multiple="item.multiple"
                  :field-names="item.optionProps" allow-clear allow-search />

                <!-- 日期类型表单 -->
                <a-date-picker v-else-if="item.type == 'datetime'" :readonly="item.readonly" :disabled="item.disabled"
                  :format="item.format ?? 'YYYY-MM-DD'" :placeholder="item.placeholder" allow-clear />

                <!-- 用户上传头像 -->
                <div class="user-avatar-container" v-else-if="item.type == 'userAvatar'">
                  <a-upload :headers="item.uploadHeaders" :action="item.uploadAction" :fileList="userAvatarFile ? [userAvatarFile] : []"
                    :show-file-list="false" @change="onChange" @progress="onProgress"
                    @before-upload="beforeUploadAvatar" @success="item.uploadSuccess" accept=".jpg, .png">
                    <template #upload-button>
                      <div :class="`arco-upload-list-item${userAvatarFile && userAvatarFile.status === 'error' ? ' arco-upload-list-item-error' : ''
                        }`">
                        <!-- 如果有值，则显示头像，否则显示默认头像 -->
                        <div class="arco-upload-list-picture custom-upload-avatar" v-if="localForm[item.field]">
                          <img :src="localForm[item.field]" />
                          <div class="arco-upload-list-picture-mask">
                            <IconEdit />
                          </div>
                          <a-progress v-if="userAvatarFile.status === 'uploading' && userAvatarFile.percent < 100" :percent="userAvatarFile.percent"
                            type="circle" size="mini" :style="{
                              position: 'absolute',
                              left: '50%',
                              top: '50%',
                              transform: 'translateX(-50%) translateY(-50%)',
                            }" />
                        </div>
                        <div class="arco-upload-picture-card" v-else>
                          <div class="arco-upload-picture-card-text">
                            <IconPlus />
                            <div style="margin-top: 10px; font-weight: 600">上传头像</div>
                          </div>
                        </div>
                        <a-tooltip content="只能上传jpg/png文件，且不超过500kb" position="rt">
                          <IconQuestionCircle />
                        </a-tooltip>
                      </div>
                    </template>
                  </a-upload>
                </div>

              </a-form-item>
            </a-col>
          </a-row>
        </a-form>
      </a-spin>
    </a-modal>
  </div>
</template>

<script setup lang="ts">
import { isDeepEqual } from '@/utils';
import { FormModalFormInfoItem } from '@/types/components'
import { FieldRule, Message } from '@arco-design/web-vue';

// 获取当前vue实例对象
const { proxy } = getCurrentInstance() as any;

// 定义属性
const props = defineProps<{
  visible: boolean;
  loading: boolean;
  okLoading: boolean;
  title: string;
  modelValue: any;
  submitButtonName: string;
  formInfo: FormModalFormInfoItem[];
  formRules: Record<string, FieldRule<any> | FieldRule<any>[]>;
  width: number | string;
}>();

// 触发事件
const emit = defineEmits(["update:modelValue", "update:visible", "submitForm"])
const localForm = ref({ ...props.modelValue })
const showDialog = ref(props.visible)

// 关闭弹窗
function handleClose() {
  showDialog.value = false
  emit("update:visible", false)
}

// 表单提交
function submitBranchForm(done: any) {
  // 对数据进行校验
  proxy.$refs.ruleFormRef.validate((error: any) => {
    done(false)
    // 没有错误，我们就直接提交表单
    if (!error) {
      emit("submitForm", localForm.value)
    }
  });
}

const userAvatarFile = ref<any>({});

const onChange = (_: any, currentFile: any) => {
  userAvatarFile.value = {
    ...currentFile,
    // url: URL.createObjectURL(currentFile.file),
  }
}
const onProgress = (currentFile: any) => {
  userAvatarFile.value = currentFile;
}

// 上传用户头像时校验后缀以及大小
const beforeUploadAvatar = (fileData: File) => {
  const isJpgOrPng = fileData.type === 'image/jpeg' || fileData.type === 'image/png';
  if (!isJpgOrPng) {
    Message.error('只能上传 JPG 或 PNG 文件!');
    return false;
  }
  const isLt500K = fileData.size / 1024 < 500;
  if (!isLt500K) {
    Message.error('文件大小不能超过 500KB!');
    return false;
  }
  return true;
}

watch(
  () => props.visible,
  (newVal) => {
    showDialog.value = newVal
    if (newVal) {
      nextTick(() => {
        proxy.$refs.ruleFormRef.clearValidate()
      })
    }
  }
);

watch(
  () => props.modelValue,
  (newVal) => {
    if (!isDeepEqual(newVal, localForm.value)) {
      localForm.value = { ...newVal }
    }
  },
  { deep: true }
);

watch(
  () => localForm.value,
  (newVal) => {
    if (!isDeepEqual(localForm.value, props.modelValue)) {
      emit("update:modelValue", localForm.value)
    }
  },
  { deep: true }
);

</script>

<style lang="less" scoped>
:deep(.arco-upload-list-item) {
  align-items: flex-end;
}
</style>